﻿using System;
using System.ComponentModel;
using PostSharp.Aspects;
using PostSharp.Aspects.Advices;
using PostSharp.Extensibility;

namespace BusinessFramework.AOP
{
    [Serializable]
    [MulticastAttributeUsage(MulticastTargets.Class, Inheritance = MulticastInheritance.Strict)]
    public sealed class AddNotifyPropertyChangingAttribute : InstanceLevelAspect
    {
        [ImportMember("OnPropertyChanging", IsRequired = false)]
        public Action<PropertyChangingEventArgs> OnPropertyChangingMethod;

        [ImportMember("OnPropertyChanging", IsRequired = false)]
        public Action<string> OnPropertyChangingStringMethod;

        [ImportMember("RaisePropertyChanging", IsRequired = false)]
        public Action<PropertyChangingEventArgs> RaisePropertyChangingMethod;

        [ImportMember("RaisePropertyChanging", IsRequired = false)]
        public Action<string> RaisePropertyChangingStringMethod;

        [OnLocationSetValueAdvice,
         MulticastPointcut(Targets = MulticastTargets.Property, Attributes = MulticastAttributes.Instance | MulticastAttributes.NonAbstract)]
        public void OnPropertySet(LocationInterceptionArgs args)
        {
            if (OnPropertyChangingMethod != null)
                OnPropertyChangingMethod(new PropertyChangingEventArgs(args.Location.Name));
            else if (OnPropertyChangingStringMethod != null)
                OnPropertyChangingStringMethod(args.Location.Name);
            else if (RaisePropertyChangingMethod != null)
                RaisePropertyChangingMethod(new PropertyChangingEventArgs(args.Location.Name));
            else if (RaisePropertyChangingStringMethod != null)
                RaisePropertyChangingStringMethod(args.Location.Name);

            // Actually sets the value.
            args.ProceedSetValue();
        }
    }
}